const G = document.querySelector.bind(document)
const H = document.createElement.bind(document)
const F = document.createDocumentFragment.bind(document)
class D {
	constructor(el) {
		this.element = el
	}
	shape(cssData) {
		for (let key in cssData) {
			this.element.style[key] = cssData[key]
		}
		return this
	}
	on(eventObj) {
		for (let key in eventObj) {
			this.element.addEventListener(key, (e) => {
				eventObj[key](e, this)
			})
		}
		return this
	}
	click() {
		this.element.click()
		return this
	}
	get previous() {
		let previousNode = this.element.previousSibling
		while (previousNode.nodeName === ('#text' || '#comment')) {
			previousNode = previousNode.nextSibling
		}
		return new D(previousNode)
	}
	get next() {
		let nextNode = this.element.nextSibling
		while (nextNode.nodeName === ('#text' || '#comment')) {
			nextNode = nextNode.nextSibling
		}
		return new D(nextNode)
	}
	child(index) {
		return new D(this.element.children[index])
	}
	get parent() {
		return new D(this.element.parentNode)
	}
	static $render(tagName, data, children) {
		const el = H(tagName)
		if (typeof data === ('string' || 'undefined')) {
			el.innerText = data
		} else if (typeof data === 'object') {
			for (let key in data) {
				el[key] = data[key]
				el.setAttribute(key, data[key])
			}
		}
		if (children === null || children === void 0 ? void 0 : children.length) {
			children.forEach((item) => {
				el.appendChild(item.element)
			})
		}
		return new D(el)
	}
	append(tagName, data) {
		if (typeof tagName === 'string') {
			this.element.appendChild(D.$render(tagName, data).element)
		} else if (typeof tagName === 'object') {
			this.element.appendChild(tagName.element)
		}
		return this
	}
	mount(root) {
		this.append(root)
	}
	update(root) {
		const id = root.element.id
		;[...this.element.children].forEach((item, index, arr) => {
			if (item.id === id) {
				if (index !== arr.length - 1) {
					const nextElement = arr[index + 1]
					this.element.removeChild(item)
					this.element.insertBefore(root.element, nextElement)
				} else {
					this.element.removeChild(item)
					this.element.appendChild(root.element)
					console.log('update')
				}
			}
		})
	}
}
const flush = (selector) => {
	return new D(G(selector))
}
window.name_space_flush = flush